package de.koller.oceanFramework.gl.util;

import de.koller.oceanFramework.util.Bytnig;
import de.koller.oceanFramework.util.ColorIntUtil;
import java.nio.ByteBuffer;

public class RasterManager implements IImageRaster {
	
	protected int width, height;
	protected byte[] pixels;
	protected boolean changed = false;
	
	public RasterManager( int width, int height ) {
		this.width = width;
		this.height = height;
		pixels = new byte[ width*height*4 ];
		clear( 0 );
	}

	public void clear( int color ) {
		for( int i = 0; i < ( width * height ); i++ ) {
			setPixelAt( i, color );
		}
	}

	@Override
	public void setColor( int color, float x, float y ) {
		setPixel( color, x, y );
	}

	@Override
	public int getColor( float x, float y ) {
		return colorAt( x, y );
	}
	
	/** color = ARGB! */
	public int colorAt( float x, float y ) {
		return getPixelAt( offsetOf( x, y ) );
	}
	
	public float intAt( int x, int y ) {
		int ro = offsetOf( x, y ) * 4;
		return Bytnig.byteToInt( new byte[] { pixels[ro], pixels[ro+1], pixels[ro+2], pixels[ro+3] } );
	}
	
	public float floatAt( int x, int y ) {
		int ro = offsetOf( x, y ) * 4;
		return Bytnig.byteToFloat( new byte[] { pixels[ro], pixels[ro+1], pixels[ro+2], pixels[ro+3] } );
	}
	
	public byte[] getData() {
		return pixels;
	}
	
	public int offsetOf( float x, float y ) {
		if( x < 0 || y < 0 || x >= width || y >= height ) {
			return -1;
		}
		return ( int ) y * width + ( int ) x;
	}

	/** color = ARGB! */
	public void setPixel( int color, float x, float y ) {
		int i = offsetOf( x, y );
		if( i < 0 || i >= ( width * height ) ) {
			return;
		}
		setPixelAt( i, color );
	}

	public float xFromOffset( int offset ) {
		int ax = offset - ( int ) ( ( float ) offset / ( float ) width ) * width;
		return ax;
	}

	public float yFromOffset( int offset ) {
		int ay = offset / width;
		return ay;
	}
	
	/** color = ARGB! */
	private int getPixelAt( int offset ) {
		int ro = offset * 4;
		return ColorIntUtil.getIntColor( pixels[ro+3] & 0xff, pixels[ro+0] & 0xff, pixels[ro+1] & 0xff, pixels[ro+2] & 0xff );
	}
	
	/** color = ARGB! */
	private void setPixelAt( int offset, int color ) {
		int ro = offset * 4;
		byte[] b = ColorIntUtil.getRGBA( color );
		pixels[ro+0] = b[0];
		pixels[ro+1] = b[1];
		pixels[ro+2] = b[2];
		pixels[ro+3] = b[3];
		changed = true;
	}

	@Override
	public int getHeight() {
		return height;
	}

	@Override
	public int getWidth() {
		return width;
	}
	
	public void flipHorizontal() {
		int cs[][] = new int[ width][ height ];
		for( int x = 0; x < width; x++ )
			for( int y = 0; y < height; y++ )
				cs[x][y] = colorAt( x, y );
		for( int x = 0; x < width; x++ )
			for( int y = 0; y < height; y++ )
				setPixel( cs[x][y], x, height-y-1 );
	}
	
	public ByteBuffer generateByteBuffer() {
		ByteBuffer buffer = ByteBuffer.allocateDirect( pixels.length );
		buffer.put( pixels ).flip();
		return buffer;
	}
	
}
